package com.itheima.stock.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.itheima.stock.entity.*;
import com.itheima.stock.enums.CodeEnum;
import com.itheima.stock.mapper.*;
import com.itheima.stock.properties.MarketProperties;
import com.itheima.stock.response.ResponseResult;
import com.itheima.stock.service.StockService;
import com.itheima.stock.util.DateTimeUtil;
import com.itheima.stock.vo.InnerMarketVO;
import com.itheima.stock.vo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author zby
 * @created 2024-06-23 16:34
 * @description 股票业务实现类
 */
@Service
@Slf4j
public class StockServiceImpl implements StockService {


    private final StockBusinessMapper stockBusinessMapper;
    private final MarketProperties marketProperties;
    private final StockMarketIndexInfoMapper stockMarketIndexInfoMapper;
    private final StockMarketLogPriceMapper stockMarketLogPriceMapper;
    private final StockBlockRtInfoMapper stockBlockRtInfoMapper;
    private final StockRtInfoMapper stockRtInfoMapper;

    public StockServiceImpl(StockBusinessMapper stockBusinessMapper, MarketProperties marketProperties, StockMarketIndexInfoMapper stockMarketIndexInfoMapper, StockMarketLogPriceMapper stockMarketLogPriceMapper, StockBlockRtInfoMapper stockBlockRtInfoMapper, StockRtInfoMapper stockRtInfoMapper) {
        this.stockBusinessMapper = stockBusinessMapper;
        this.marketProperties = marketProperties;
        this.stockMarketIndexInfoMapper = stockMarketIndexInfoMapper;
        this.stockMarketLogPriceMapper = stockMarketLogPriceMapper;
        this.stockBlockRtInfoMapper = stockBlockRtInfoMapper;
        this.stockRtInfoMapper = stockRtInfoMapper;
    }


    @Override
    public List<StockBusiness> getStockBusiness() {

        return stockBusinessMapper.selectAll();
    }

    @Override
    public List<InnerMarketVO> innerIndexAll() {
        // 1. 获取国内大盘指数编码集合
        List<String> ids = marketProperties.getInner();
        // 2. 获取最近的有效的股票交易时间
        LocalDateTime last = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        // mock data
        String mockDate = "20211226105600";
        last = LocalDateTime.parse(mockDate, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        // 3. 查询
        // 3.1 根据大盘编码和日期查询 股票大盘数据详情表
        List<InnerMarketDomain> marketIndexInfoList = stockMarketIndexInfoMapper.selectByIdsAndDateTime(ids, last);
        // 3.2 根据大盘编码和日期查询 股票大盘 开盘价与前收盘价流水表
        LocalDate localDate = last.toLocalDate();
        List<StockMarketLogPrice> marketLogPriceList = stockMarketLogPriceMapper.selectByIdsAndDateTime(ids, localDate);
        //4. 组装数据
        return marketIndexInfoList.stream().map((marketIndexInfo) -> {
                    InnerMarketVO vo = InnerMarketVO.builder()
                            .code(marketIndexInfo.getMarkId())
                            .name(marketIndexInfo.getMarkName())
                            .curDate(marketIndexInfo.getCurTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().toString())
                            .tradeAmt(marketIndexInfo.getTradeAccount())
                            .tradeVol(marketIndexInfo.getTradeVolume())
                            .tradePrice(marketIndexInfo.getCurrentPrice())
                            .upDown(marketIndexInfo.getUpdownRate())
                            .build();
                    marketLogPriceList.forEach((marketLogPrice) -> {
                        if (marketLogPrice.getMarketCode().equals(marketIndexInfo.getMarkId())) {
                            vo.setOpenPrice(marketLogPrice.getOpenPrice());
                            vo.setPreClosePrice(marketLogPrice.getPreClosePrice());
                        } else {
                            vo.setOpenPrice(BigDecimal.ZERO);
                            vo.setPreClosePrice(BigDecimal.ZERO);
                        }
                    });
                    return vo;
                }
        ).toList();
    }

    @Override
    public ResponseResult<List<StockBlockRtInfo>> sectorAllLimit() {
        //1.调用mapper接口获取数据 TODO 优化 避免全表查询 根据时间范围查询，提高查询效率
        List<StockBlockRtInfo> infos=stockBlockRtInfoMapper.sectorAllLimit();
        log.info("List<StockBlockRtInfo>的值：{}",infos);
        //2.组装数据
        if (CollectionUtils.isEmpty(infos)) {
            return ResponseResult.error(CodeEnum.NO_RESPONSE_DATA);
        }
        log.info("组装后List<StockBlockRtInfo>的值：{}",infos);
        return ResponseResult.ok(infos);
    }

    /**
     * 沪深两市个股涨幅分时行情数据查询，以时间顺序和涨幅查询前10条数据
     * @return
     */
    @Override
    public ResponseResult<List<StockUpdownDomain>> stockIncreaseLimit() {
        //1.直接调用mapper查询前10的数据 TODO 以时间顺序取前10
        //优化：
        //获取当前最近有效时间
        LocalDateTime curDateTime = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //mock数据
        String mockStr="2021-12-27 09:47:00";
        curDateTime=LocalDateTime.parse(mockStr,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

        List<StockUpdownDomain> infos=stockRtInfoMapper.stockIncreaseLimit(curDateTime);
        //2.判断是否有数据
        if (CollectionUtils.isEmpty(infos)) {
            return ResponseResult.error(CodeEnum.NO_RESPONSE_DATA);
        }
        return ResponseResult.ok(infos);
    }

    @Override
    public ResponseResult<PageResult<StockUpdownDomain>> stockPage(Integer page, Integer pageSize) {
        //1.设置分页参数
        PageHelper.startPage(page,pageSize);
        //2.通过mapper查询
        List<StockUpdownDomain> infos= stockRtInfoMapper.stockAll();
        if (CollectionUtils.isEmpty(infos)) {
            return ResponseResult.error(CodeEnum.NO_DATA_NOW);
        }
        //3.封装到PageResult下
        //3.1 封装PageInfo对象
        PageInfo<StockUpdownDomain> listPageInfo = new PageInfo<StockUpdownDomain>(infos);
        //3.2 将PageInfo转PageResult
        PageResult<StockUpdownDomain> pageResult = new PageResult<>(listPageInfo);
        //4.封装R响应对象
        return ResponseResult.ok(pageResult);
    }

    /**
     * 功能描述：沪深两市涨跌停分时行情数据查询，查询T日每分钟的涨跌停数据（T：当前股票交易日）
     * 		查询每分钟的涨停和跌停的数据的同级；
     * 		如果不在股票的交易日内，那么就统计最近的股票交易下的数据
     * 	 map:
     * 	    upList:涨停数据统计
     * 	    downList:跌停数据统计
     * @return
     */
    @Override
    public ResponseResult<Map> upDownCount() {
        //1.获取股票最近的有效交易日期,精确到秒
        LocalDateTime curDateTime = DateTimeUtil.getLastDateTime4Stock(LocalDateTime.now());
        //当前最近有效期
        LocalDateTime curTime = curDateTime;
        //开盘日期
        LocalDateTime openTime = DateTimeUtil.getOpenDate(curDateTime);
        //TODO mock_data 后续数据实时获取时，注释掉
        String curTimeStr="20220106142500";
        //对应开盘日期 mock_data
        String openTimeStr="20220106092500";
        curTime = LocalDateTime.parse(curTimeStr, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        log.info("curTime--------:{}",curTime);
        openTime = LocalDateTime.parse(openTimeStr, DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        log.info("openTime---------:{}",openTime);
        //2.统计涨停的数据 约定：1代表涨停 0：跌停
        List<Map> upCount= stockRtInfoMapper.upDownCount(curTime,openTime,1);
        log.info("upCount:{}",upCount);
        //3.统计跌停的数据
        List<Map> downCount= stockRtInfoMapper.upDownCount(curTime,openTime,0);
        log.info("downCount:{}",downCount);
        //4.组装数据到map
        HashMap<String, List<Map>> info = new HashMap<>();
        info.put("upList",upCount);
        info.put("downList",downCount);
        log.info("info:{}",info);
        //5.响应
        return ResponseResult.ok(info);
    }
}